home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-04-06 | 7.5 KB | 226 lines | [TEXT/MACH] |
- .( Priority based multitasking on the Macintosh ) cr
- ( Original concept: D.Bryant, G.Caunt, G.Else 1987 )
- ( Modifications and Generalisation C.A.Maynard 1988 Wave=onic Associates)
- ( Version 1.1 060488 )
- Decimal
- ( -------------------------------------------------------------------------- )
- ( Task and window configurations for the necessary tasks )
- ( -------------------------------------------------------------------------- )
- 400 1000 background schedulertask
- 400 1000 terminal prioritytask
-
- new.window PriorityWindow
- " PRIORITIES" PriorityWindow Title ( create the priority window )
- 40 250 110 500 PriorityWindow Bounds
- Document Visible NoCloseBox GrowBox PriorityWindow Items
- PriorityWindow Add
- ( -------------------------------------------------------------------------- )
- ( DEMO Tasks and windows )
- ( -------------------------------------------------------------------------- )
- 400 1000 terminal task1
- 400 1000 terminal task2
- 400 1000 terminal task3
-
- new.window Task1Window
- " TASK 1" Task1Window Title ( create the TASK 1 window )
- 140 20 310 180 Task1Window Bounds
- Document Visible NoCloseBox NoGrowBox Task1Window Items
- Task1Window Add
-
- new.window Task2Window
- " TASK 2" Task2Window Title ( create the TASK 2 window )
- 140 180 310 340 Task2Window Bounds
- Document Visible NoCloseBox NoGrowBox Task2Window Items
- Task2Window Add
-
- new.window Task3Window
- " TASK 3" Task3Window Title ( create the TASK 3 window )
- 140 340 310 500 Task3Window Bounds
- Document Visible NoCloseBox NoGrowBox Task3Window Items
- Task3Window Add
- ( -------------------------------------------------------------------------- )
- ( USER Variable definitions )
- ( -------------------------------------------------------------------------- )
- 72 user TaskWindow
- 220 user rleft
- 224 user rright
- 228 user rtop
- 232 user rbot
- 236 user diff ( create rectangle coords as user variables for each task )
- 240 user angle
- 244 user rectangle ( space for 8 bytes needed. Next slot 252)
- ( -------------------------------------------------------------------------- )
- ( Scheduling Task Definitions )
- ( -------------------------------------------------------------------------- )
- VARIABLE LevelAddr ( Global temporary storage for the scheduler )
- VARIABLE NTASKS ( Number of runnable tasks MAX 10)
- 0 NTASKS ! ( Initialise to zero )
- VARIABLE PTASKS 120 VALLOT
- ( Storage for Level, Priority and Task Address )
- : Wakeup ( a1 - )
- ( Wakeup gets the next task running given the status address )
- sleep status W!
- wake swap W! pause ;
-
- : SwitchTask
- ( Call the scheduler to see who's next )
- sleep status W!
- wake status task-> schedulertask W!
- pause ;
-
- : SCHED
- ( Define a general task scheduling process )
- activate
- begin
- NTasks @ dup 0> if ( only execute defined tasks )
- 0 DO
- I 12 * PTasks + dup LevelAddr ! @ ( Get the address and current level )
- LevelAddr @ 4 + @ ( Get priority setting )
- + dup LevelAddr @ ! ( Save new level )
- 100 - dup 0> if ( Modify level if necessary )
- LevelAddr @ !
- LevelAddr @ 8 + @ Wakeup
- else
- drop
- then
- LOOP
- else drop then pause
- again ;
- ( -------------------------------------------------------------------------- )
- cr
- .( Clive Maynard's Forth Environment extract ) cr
- .( C.A.Maynard 020488 ) cr
-
- also assembler
-
- code LVALLOT ( n - addr )
- ( Set up a local buffer. Only callable from a word with local variables )
- ( UNLK will clean up the stack. USER beware of buffer overflow!!! )
- MOVE.L (A6)+,D0 ( GET SIZE IN BYTES )
- MOVEA.L (A7)+,A0 ( GET RETURN INFO )
- SUBA.L D0,A7 ( NEW SP )
- MOVE.L A7,-(A6) ( COPY ADDRESS TO PARAMETER STACK )
- JMP (A0)
- end-code
-
- -1 CONSTANT TRUE
- 0 CONSTANT FALSE
-
- : #terminator? ( char - f )
- ( check for the terminator of a number: space or CR )
- case
- 13 of true swap endof
- 32 of true swap endof
- false swap
- endcase ;
-
- : PTexpect { buffad nchars | buffadd countup - }
- ( Fills a buffer but includes Priority Task switching )
- buffad 1 + -> buffadd 0 -> countup
- nchars 0 do
- begin
- SwitchTask
- ?terminal until
- key dup emit dup buffadd C! 1 +> buffadd 1 +> countup
- #terminator? if leave then
- loop
- countup buffad c! ;
-
- : #IN { | buffaddr - number }
- ( PC/FORTH intrinsic function!! )
- ( Collect into a 10 byte buffer and return a number input )
- 10 lvallot ( set up a local buffer very carefully )
- -> buffaddr
- buffaddr 10 PTexpect
- buffaddr number? drop ;
- ( -------------------------------------------------------------------------- )
- ( A new task building word for Priority Tasks )
- ( -------------------------------------------------------------------------- )
- : PBUILD { TaskAddr | LevelAdr - }
- ( Initialise conditions for new tasks )
- NTasks 10 = abort" Task Priority Table Full. New entry denied"
- NTasks @ 12 * PTasks + ( Get offset into table )
- dup -> LevelAdr 0 swap ! ( Set Level to zero )
- 10 LevelAdr 4 + ! ( Set Priority to default of 10 )
- TaskAddr BUILD ( Now do an ordinary task build )
- TaskAddr @ LevelAdr 8 + ! ( Save Status address )
- NTasks @ 1+ NTasks ! ( Increase task count )
- ;
- ( -------------------------------------------------------------------------- )
- ( The Priority Task Definition )
- ( -------------------------------------------------------------------------- )
- : getbuff { | taskno priority - }
- ( priority reallocation routine)
- #in dup ." Task " . -> taskno cr
- taskno NTasks @ < taskno 0> and if
- #in dup 0< if drop 0 then dup ." Priority " . -> priority ( New priority determined )
- priority 101 < IF
- priority dup 0= if cr ." Zero or negative priority halts the task" cr then
- taskno 12 * 4 + PTasks + ! ( Get to priority storage location )
- ELSE cr ." Priority out of range. No change" cr THEN
- else cr ." Task number out of range. No change" cr then ;
-
- : setpriority ( priority allocation task)
- activate
- begin
- taskwindow @ call SetPort
- ." Enter the task number followed by" cr ." its desired priority" cr
- ." Priorities can be from 0 to 100" cr
- ?terminal if
- getbuff cr then
- SwitchTask
- again ;
- ( -------------------------------------------------------------------------- )
- ( The other tasks )
- ( -------------------------------------------------------------------------- )
- : DISKS
- activate
- ( Initialise variables )
- -7 diff ! 0 angle !
- 10 rleft W! 20 rtop W!
- 150 rright W! 160 rbot W!
- ( Loop through graphic changes in superb animation )
- begin
- rectangle rleft W@ rtop W@ rright W@ rbot W@ call SetRect
- begin
- 359 angle @ - 0>
- while
- taskwindow @ call SetPort
- angle @ 10 + angle !
- rectangle angle @ 10 call InvertArc
- SwitchTask
- repeat
- taskwindow @ call SetPort
- rright W@ diff @ + rright W!
- rbot W@ diff @ + rbot W!
- rright W@ rleft W@ - 5 < if
- 7 diff ! then
- rright W@ rleft W@ - 140 > if
- rectangle 0 360 call EraseRect -7 diff ! then
- 0 angle !
- SwitchTask ( Get back to the scheduler )
- again ;
- ( -------------------------------------------------------------------------- )
- ( Initiate the necessary tasking operations )
- ( -------------------------------------------------------------------------- )
- schedulertask build ( slot the scheduler into the round robin loop )
- schedulertask sched
-
- prioritywindow prioritytask Pbuild
- prioritytask setpriority
- ( -------------------------------------------------------------------------- )
- .( Define task insertion words to show adding tasks to priority system ) cr
- .( Shrink Mach 2 window to top left corner ) cr
- .( Execute task words: atask, btask and ctask after loading the file ) cr
- .( Change priority through the priority task window ) cr
- ( -------------------------------------------------------------------------- )
- : Atask task1window task1 Pbuild
- task1 disks ;
-
- : Btask task2window task2 Pbuild
- task2 disks ;
-
- : Ctask task3window task3 Pbuild
- task3 disks ;
-
-